<?php
import( 'de.ceus-media.ui.html.Elements' );
/**
 *	Paging System for Lists.
 *	@package		mv2.view.component
 *	@uses			Elements
 *	@author			Christian Würker <Christian.Wuerker@CeuS-Media.de>
 *	@since			01.12.2005
 *	@version		0.2
 */
/**
 *	Paging System for Lists.
 *	@package		mv2.view.component
 *	@uses			Elements
 *	@author			Christian Würker <Christian.Wuerker@CeuS-Media.de>
 *	@since			01.12.2005
 *	@version		0.2
 */
class View_Component_Paging
{
	/**	@var		Elements		$html		Instance of HTML Elements Class */
	var $html		= null;
	var $uri;
	var $param;
	var $coverage;
	var $extreme;
	var $more;
	var $indent;
	var $key_request;
	var $key_param;
	var $key_assign;
	var $key_offset;
	var $class_span;
	var $class_link;
	var $class_text;
	var $text_first;
	var $text_previous;
	var $text_next;
	var $text_last;
	var $text_more;
	var $key_first;
	var $key_previous;
	var $key_next;
	var $key_last;
	
	
	
	/**
	 *	Constructor.
	 *	@access		public
	 *	@return		void
	 */
	public function __construct()
	{
		$this->html	= new Elements;

		$this->uri				= "index.php";
		$this->param			= array();
		$this->coverage			= "2";
		$this->extreme			= "1";
		$this->more				= "1";
		$this->indent			= "\n\t";
		$this->key_request		= "?";
		$this->key_param		= "&";
		$this->key_assign		= "=";
		$this->key_offset		= "offset";
		$this->class_span		= "paging";
		$this->class_link		= "paging";
		$this->class_text		= "text";

		$this->text_first		= "<<";
		$this->text_previous	= "<";
		$this->text_next		= ">";
		$this->text_last		= ">>";
		$this->text_more		= "..";

		$this->key_first		= '';
		$this->key_previous		= '';
		$this->key_next			= '';
		$this->key_last			= '';
	}
	
	/**
	 *	Builds HTML for Paging of Lists.
	 *	@access		public
	 *	@param		int			$amount			Total amount of entries
	 *	@param		int			$limit			Maximal amount of displayed entries
	 *	@param		int			$offset			Currently offset entries
	 *	@return		string
	 */
	public function build( $amount, $limit, $offset )
	{
		$pages	= array();
		if( $limit && $amount > $limit )
		{
			$offset		= ( (int)$offset >= 0 ) ? (int)$offset : 0;												//  reset invalid negative offsets
			$offset		= ( 0 !== $offset % $limit ) ? ceil( $offset / $limit ) * $limit : $offset;							//  synchronise invalid offsets
			$here		= ceil( $offset / $limit );																//  current page
			$before		= (int)$offset / (int)$limit;															//  pages before
			if( $before )
			{
				if( $this->extreme && $before > $this->extreme )														//  first page
					$pages[]	= $this->buildButton( 'text_first', 'class_link', 0, 'class_link' );
				$pages[]	= $this->buildButton( 'text_previous', 'class_link', ( $here - 1 ) * $limit, 'class_link' );			//  previous page
				if( $this->more && $before > $this->coverage )															//  more before pages
					$pages[]	= $this->buildButton( 'text_more', 'class_text' );
				for( $i=max( 0, $before - $this->coverage ); $i<$here; $i++ )											//  before pages
					$pages[]	= $this->buildButton( $i + 1, 'class_link', $i * $limit, 'class_link' );
/*				if( $this->key_previous )
				{
					$latest	= count( $pages ) - 1;
					$button	= $this->buildButton( $i, 'class_link', ($i-1) * $limit, 'class_link', 'previous' );
					$pages[$latest]	= $button;
				}*/
			}
			
			$pages[]	= $this->buildButton( $here + 1, 'class_text' );												//  page here
			$after	= ceil( ( ( $amount - $limit ) / $limit ) - $here );											//  pages after
			if( $after )
			{
				for( $i=0; $i<min( $this->coverage, $after ); $i++ )													//  after pages
					$pages[]	= $this->buildButton( $here + $i + 2, 'class_link', ( $here + $i + 1 ) * $limit, 'class_link' );
				if( $this->more && $after > $this->coverage )															//  more after pages
					$pages[]	= $this->buildButton( 'text_more', 'class_text' );
				$pages[]	= $this->buildButton( 'text_next', 'class_link', ( $here + 1 ) * $limit, 'class_link' );			//  next page
				if( $this->extreme && $after > $this->extreme )														//  last page
					$pages[]	= $this->buildButton( 'text_last', 'class_link', ( $here + $after ) * $limit, 'class_link' );
			}
		}
		$pages	= implode( $this->indent, $pages );
		return $pages;
	}

	//  -- PRIVATE METHODS   --  //
	/**
	 *	Builds HTML Link of Paging Button.
	 *	@access		private
	 *	@param		int			$offset			Currently offset entries
	 *	@return		string
	 */
	private function buildLink( $offset )
	{
		$param	= $this->param;
		$param[$this->key_offset] = $offset;
		$_list	= array();
		foreach( $param as $key => $value )
			$_list[]	= $key.$this->key_assign.$value;
		$param	= implode( $this->key_param, $_list );
		$link	= $this->uri.$this->key_request.$param;
		return $link;
	}
	
	/**
	 *	Builds Span Link of Paging Button.
	 *	@access		private
	 *	@param		string		$text			Text or HTML of Paging Button Span
	 *	@param		string		$class			Additive Style Class of Paging Button Span
	 *	@return		string
	 */
	private function buildSpan( $text, $class = false )
	{
		$class 	= $class ? $this->class_span." ".$class : $this->class_span;
		$span	= "<span class='".$class."'>".$text."</span>";
		return $span;
	}
	
	/**
	 *	Builds Paging Button.
	 *	@access		private
	 *	@param		string		$text			Text or HTML of Paging Button Span
	 *	@param		string		$span_class		Additive Style Class of Paging Button Span
	 *	@param		int			$offset			Currently offset entries
	 *	@param		string		$link_class		Style Class of Paging Button Link
	 *	@return		string
	 */
	private function buildButton( $text, $span_class, $offset = false, $link_class = false, $key = false )
	{
		$text	= isset( $this->$text ) ? $this->$text : $text;
		if( "" !== $text )
		{
			$span_class	= isset( $this->$span_class ) ? $this->$span_class : "";
			if( false !== $offset )
			{
				$link_class	= $this->$link_class ? $this->$link_class : "";
				$url		= $this->buildLink( $offset );
				$key		= $key ? $this->{'key_'.$key} : "";
				$text		= $this->html->Link( $url, $text, $link_class, false, false, false, $key );
			}
			return $this->buildSpan( $text, $span_class );
		}
	}
}
?>